﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.IO;
using System.Threading;

namespace XMM.Dialoges.Library
{
    /// <summary>
    /// Interaktionslogik für ImportDisc.xaml
    /// </summary>
    public partial class ImportDisc : Window
    {
        XMM.Library ParentLibrary { get; set; }
        Settings XMMConfig { get { return new Settings(); } }

        List<Objects.DiscDrive> AvailableDiscDrives = new List<Objects.DiscDrive>();

        Objects.DiscDrive _SelectedDiscDrive;
        public Objects.DiscDrive SelectedDiscDrive { get { return _SelectedDiscDrive; } }

        Objects.MediaInfo _NewMediaInfo;
        public Objects.MediaInfo NewMediaInfo { get { return _NewMediaInfo; } }

        int _MediaType;
        public int MediaType { get { return _MediaType; } }

        public ImportDisc(XMM.Library dlgParentLibrary)
        {
            InitializeComponent();

            ParentLibrary = dlgParentLibrary;
            _NewMediaInfo = new Objects.MediaInfo();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            UpdateDrives();
            prefetchShows();
        }

        private void UpdateDrives()
        {
            cmbDrive.Items.Clear();
            AvailableDiscDrives.Clear();

            DriveInfo[] drives = DriveInfo.GetDrives();

            foreach (DriveInfo drive in drives)
            {
                if (drive.DriveType == DriveType.CDRom || drive.DriveType == DriveType.Ram)
                {
                    if (drive.IsReady)
                        AvailableDiscDrives.Add(new Objects.DiscDrive(drive.Name.Substring(0, 1), drive.VolumeLabel));
                    else
                        AvailableDiscDrives.Add(new Objects.DiscDrive(drive.Name.Substring(0, 1), String.Empty));
                }
            }

            if (AvailableDiscDrives != null && AvailableDiscDrives.Count > 0)
            {
                foreach (Objects.DiscDrive oDrive in AvailableDiscDrives)
                {
                    cmbDrive.Items.Add(oDrive);
                }
            }
        }

        private void rdbMovie_Checked(object sender, RoutedEventArgs e)
        {
            grdMediaDetails.Children.Clear();

            _MediaType = 1;
            _NewMediaInfo.FileName = "Neue DVD";
            _NewMediaInfo.FullPath = Tools.getInstallationPath() + "temp";
            _NewMediaInfo.MediaType = 1;

            Controls.Library.Import_Movie ctlImportMovie = new Controls.Library.Import_Movie(NewMediaInfo);
            ctlImportMovie.ctlFiles.IsEnabled = false;
            ctlImportMovie.ctlFiles.Visibility = System.Windows.Visibility.Collapsed;
            ctlImportMovie.ctlAudioInfo.IsEnabled = false;
            ctlImportMovie.ctlAudioInfo.Visibility = System.Windows.Visibility.Collapsed;
            ctlImportMovie.ctlVideoInfo.IsEnabled = false;
            ctlImportMovie.ctlVideoInfo.Visibility = System.Windows.Visibility.Collapsed;
            ctlImportMovie.ctlDiskMedia.IsEnabled = false;
            ctlImportMovie.ctlDiskMedia.Visibility = System.Windows.Visibility.Collapsed;

            grdMediaDetails.Children.Add(ctlImportMovie);
        }

        private void rdbShow_Checked(object sender, RoutedEventArgs e)
        {
            grdMediaDetails.Children.Clear();

            _MediaType = 2;
            _NewMediaInfo.FileName = "Neue DVD";
            _NewMediaInfo.FullPath = Tools.getInstallationPath() + "temp";
            _NewMediaInfo.MediaType = 2;

            Controls.Library.Import_Episode ctlImportEpisode = new Controls.Library.Import_Episode(this, NewMediaInfo);
            grdMediaDetails.Children.Add(ctlImportEpisode);
        }

        Mutex mutPrefetchShows = new Mutex();
        bool IsPrefetching { get; set; }

        ObservableCollection<Objects.Series> _AvailableSeries;
        public ObservableCollection<Objects.Series> AvailableSeries { get { return _AvailableSeries; } }

        /// <summary>
        /// Prefetch Shows.
        /// </summary>
        private void prefetchShows()
        {
            if (mutPrefetchShows.WaitOne(500))
            {
                IsPrefetching = true;
                //Dispatcher.Invoke(new updateStatusCallback(updateStatus), new object[] { 0, "Lade verfügbare Serien..." });
                _AvailableSeries = new ObservableCollection<Objects.Series>();
                List<Objects.Series> lSeries = Objects.Series.getAllSeries();

                int iShowPercentage = 0;
                if (lSeries.Count != 0)
                    iShowPercentage = (int)Math.Round(((decimal)100 / lSeries.Count), 0);

                int iCurrentShow = 1;

                if (lSeries != null && lSeries.Count > 0)
                {
                    foreach (Objects.Series oSeries in lSeries)
                    {
                        int iCurrentPercentage = iCurrentShow * iShowPercentage;
                        if (iCurrentPercentage > 100)
                            iCurrentPercentage = 100;

                        //Dispatcher.Invoke(new updateStatusCallback(updateStatus), new object[] { iCurrentPercentage, "Lade Serie " + iCurrentShow.ToString() + " of " + lSeries.Count.ToString() + "..." });
                        _AvailableSeries.Add(oSeries);

                        ++iCurrentShow;
                    }
                }

                //Dispatcher.Invoke(new updateStatusCallback(updateStatus), new object[] { 0, "Bereit..." });
                IsPrefetching = false;

                // Release Prefetch-Mutex.
                mutPrefetchShows.ReleaseMutex();
            }
        }

        private void cmbDrive_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            _SelectedDiscDrive = null;

            if (cmbDrive.SelectedIndex > -1)
            {
                _SelectedDiscDrive = (Objects.DiscDrive)cmbDrive.SelectedItem;
            }
        }



        private void btnRefreshDrives_Click(object sender, RoutedEventArgs e)
        {
            UpdateDrives();
        }

        private void btnAbort_Click(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show("Wirklich abbrechen? Änderungen gehen verloren!", "Abbrechen", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                this.DialogResult = false;
                Close();
            }
        }

        private void btnImport_Click(object sender, RoutedEventArgs e)
        {
            if (MediaType != 0 && SelectedDiscDrive != null)
            {
                switch (MediaType)
                {
                    case 1:
                        ImportMovie();
                        break;
                    case 2:
                        ImportEpisode();
                        break;
                }
            }
        }

        private void ImportMovie()
        {
            if (SelectedDiscDrive != null)
            {
                Tools.checkMediaLibraryPath();

                Controls.Library.Import_Movie ctlImportMovie = (Controls.Library.Import_Movie)grdMediaDetails.Children[0];
                Objects.Movie oMovie = ctlImportMovie.getCurrentData;

                if (oMovie.Files.Count > 0 && oMovie.Name != String.Empty)
                {
                    // Create VLC-Playlist
                    Objects.DVDPlaylist oPlaylist = new Objects.DVDPlaylist(XMMConfig.LibraryDataStorage + @"movies\discs\" + oMovie.Name.Replace(' ', '.') + ".xspf", SelectedDiscDrive.DriveLetter, oMovie.Name);
                    if (oPlaylist.Save() == true)
                    {
                        oMovie.Files = new List<string>() { oPlaylist.Path };
                        if (oMovie.SaveNew())
                        {
                            try
                            {
                                Settings oSettings = new Settings();
                                string sCoverImagePath = ctlImportMovie.ctlCoverArt.CoverImagePath;
                                System.Drawing.Bitmap bmpCoverImage = new System.Drawing.Bitmap(ctlImportMovie.ctlCoverArt.CoverImagePath);
                                System.Drawing.Bitmap bmpCoverThumb = Functions.Imaging.ResizeBitmap(bmpCoverImage, (int)(bmpCoverImage.Width / 10), (int)(bmpCoverImage.Height / 10));
                                bmpCoverImage.Save(oSettings.LibraryDataStorage + "movies\\images\\xmm_" + oMovie.Name.Replace(' ', '.') + ".xspf.jpg");
                                bmpCoverThumb.Save(oSettings.LibraryDataStorage + "movies\\thumb\\xmm_" + oMovie.Name.Replace(' ', '.') + ".xspf.jpg");
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show("Fehler beim Speichern des Cover-Bildes: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                            }
                            ParentLibrary.RefreshXMM();
                            this.Close();
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Unvollständige Angaben!", "Unvollständige Angaben!", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
            else
            {
                MessageBox.Show("Wählen Sie zuerst ein Laufwerk für die Wiedergabe aus!", "Kein Laufwerk ausgewählt", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void ImportEpisode()
        {
            if (SelectedDiscDrive != null)
            {
                Tools.checkMediaLibraryPath();

                Controls.Library.Import_Episode ctlImportEpisode = (Controls.Library.Import_Episode)grdMediaDetails.Children[0];
                Objects.SeriesEpisode oEpisode = ctlImportEpisode.CurrentData;

                if (oEpisode.MediaFile != String.Empty && oEpisode.SeriesID != 0 && oEpisode.SeasonID != 0 && oEpisode.EpisodeNo != 0)
                {
                    Objects.Series oShow = new Objects.Series(oEpisode.SeriesID);
                    Objects.SeriesSeason oSeason = new Objects.SeriesSeason(oEpisode.SeasonID);

                    string sPlaylistPath = XMMConfig.LibraryDataStorage + @"series\discs\" + oEpisode.SeriesID.ToString() + "-" + oEpisode.SeasonID.ToString() + "-" + oEpisode.EpisodeNo.ToString() + ".xspf";

                    Objects.DVDPlaylist oPlaylist = new Objects.DVDPlaylist(sPlaylistPath, SelectedDiscDrive.DriveLetter, oShow.Name + " (S" + oSeason.Number.ToString() + " E" + oEpisode.EpisodeNo.ToString() + ")");
                    if (oPlaylist.Save() == true)
                    {
                        oEpisode.MediaFile = oPlaylist.Path;
                        if (oEpisode.SaveNew())
                        {
                            ParentLibrary.RefreshXMM();
                            this.Close();
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Unvollständige Angaben!", "Unvollständige Angaben!", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
            else
            {
                MessageBox.Show("Wählen Sie zuerst ein Laufwerk für die Wiedergabe aus!", "Kein Laufwerk ausgewählt", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }
    }
}
